package ewms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import ewms.bo.EwmsWasteFlowInfoQueryBo;
import ewms.bo.EwmsReportQueryBo;
import ewms.mapper.EwmsReportMapper;
import ewms.service.IEwmsReportService;
import ewms.vo.EwmsReportVo;
import ewms.common.core.page.TableDataInfo;
import ewms.common.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class EwmsReportServiceImpl implements IEwmsReportService {

	@Autowired
	private EwmsReportMapper reportMapper;

	@Override
	public TableDataInfo<EwmsReportVo.WasteFlowInfoVo> selectWasteFlowInfoList(EwmsWasteFlowInfoQueryBo bo) {
		Page<EwmsReportVo.WasteFlowInfoVo> wasteFlowInfoList = reportMapper.selectWasteFlowInfoList(PageUtils.buildPage(), bo);
		return PageUtils.buildDataInfo(wasteFlowInfoList);
	}

	@Override
	public List<EwmsReportVo.EntryWarehouseReportVo> selectWasteEntryWarehouseList(EwmsReportQueryBo bo) {
		List<EwmsReportVo.EntryWarehouseReportVo> list = reportMapper.selectWasteEntryWarehouseList(bo);
		// 最后一行添加统计行
		if (CollectionUtil.isNotEmpty(list)) {
			BigDecimal sumWasteWeight = list.stream().map(entryWarehouseReportVo -> entryWarehouseReportVo.getWasteWeight()).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
			Integer sumContainCount = list.stream().map(entryWarehouseReportVo -> entryWarehouseReportVo.getContainCount()).reduce(Integer::sum).orElse(0);
			EwmsReportVo.EntryWarehouseReportVo sumVo = new EwmsReportVo.EntryWarehouseReportVo();
			sumVo.setEntryDate("合计")
				.setContainCount(sumContainCount)
				.setWasteWeight(sumWasteWeight)
				.setCreateBy("-")
				.setWasteName("-")
				.setWarehouseName("-")
				.setPackageType("-")
				.setPackageTypeName("-")
				.setPersonSignature("-");
			list.add(sumVo);
		}
		return list;
	}

	@Override
	public List<EwmsReportVo.OutWarehouseReportVo> selectWasteOutWarehouseList(EwmsReportQueryBo bo) {
		List<EwmsReportVo.OutWarehouseReportVo> list = reportMapper.selectWasteOutWarehouseList(bo);
		// 最后一行添加统计行
		if (CollectionUtil.isNotEmpty(list)) {
			BigDecimal sumOutWeight = list.stream().map(EwmsReportVo.OutWarehouseReportVo::getOutWeight).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
			BigDecimal sumInventoryWeight = list.stream().map(EwmsReportVo.OutWarehouseReportVo::getInventoryWeight).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
			Integer sumContainCount = list.stream().map(entryWarehouseReportVo -> entryWarehouseReportVo.getContainCount()).reduce(Integer::sum).orElse(0);
			EwmsReportVo.OutWarehouseReportVo sumVo = new EwmsReportVo.OutWarehouseReportVo();
			sumVo.setOutDate("合计")
				.setContainCount(sumContainCount)
				.setOutWeight(sumOutWeight)
				.setInventoryWeight(sumInventoryWeight)
				.setPersonSignature("-")
				.setCreateBy("-")
				.setWarehouseName("-")
				.setHandleMethodName("-")
				.setPackageType("-")
				.setPackageTypeName("-")
				.setWasteName("-");
			list.add(sumVo);
		}
		return list;
	}

	@Override
	public List<EwmsReportVo.EntryAndOutWarehouseMonthReportVo> selectEntryAndOutWarehouseMothReport(EwmsReportQueryBo bo) {
		return reportMapper.selectEntryAndOutWarehouseMothReport(bo);
	}

	@Override
	public List<EwmsReportVo.WasteOutFactoryReportVo> selectOutFactoryReport(EwmsReportQueryBo bo) {
		return reportMapper.selectOutFactoryReport(bo);
	}

	@Override
	public Map<String, Object> selectIncinerateHandleReport(EwmsReportQueryBo bo) {
		List<EwmsReportVo.WasteIncinerateHandleReportTempVo> tempVoList = reportMapper.selectIncinerateHandleReport(bo);

		// 1.准备数据 分离各类数据
		Map<String, BigDecimal> dataMap = new HashMap<>();
		Set<Map.Entry<String, String>> wasteSet = new LinkedHashSet<>();
		Set<String> dateSet = new LinkedHashSet<>();
		for (EwmsReportVo.WasteIncinerateHandleReportTempVo tempVo : tempVoList) {
			dataMap.put(tempVo.getDateWasteId(), tempVo.getWasteWeight());
			wasteSet.add(new AbstractMap.SimpleEntry(tempVo.getWasteId(), tempVo.getWasteName()));
			dateSet.add(tempVo.getReportDate());
		}

		// 2.数据结构转换：行转列
		List<Map> dataList = new ArrayList<>();
		Map<String, List<BigDecimal>> temSumItemMap = new HashMap<>();
		for (String date : dateSet) {
			Map<String, Object> itemMap = new LinkedHashMap<>();
			for (Map.Entry entry : wasteSet) {
				itemMap.put("date", date);
				String wasteId = (String) entry.getKey();
				BigDecimal wasteWeight = Optional.ofNullable(dataMap.get(date + "-" + wasteId)).orElse(BigDecimal.ZERO);
				itemMap.put(wasteId, wasteWeight);

				// 准备需要合计的数据
				List<BigDecimal> wasteWeightList = temSumItemMap.get(wasteId);
				if (Objects.isNull(wasteWeightList)) {
					wasteWeightList = new ArrayList<>();
					wasteWeightList.add(wasteWeight);
					temSumItemMap.put(wasteId, wasteWeightList);
				} else {
					wasteWeightList.add(wasteWeight);
				}
			}
			dataList.add(itemMap);
		}

		// 3.计算合计行数据
		if (CollectionUtil.isNotEmpty(dataList)) {
			Map<String, Object> sumItemMap = temSumItemMap.entrySet().stream().map(entry -> {
				List<BigDecimal> tempWeightList = entry.getValue();
				BigDecimal sumWeight = tempWeightList.stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
				return new AbstractMap.SimpleEntry<>(entry.getKey(), sumWeight);
			}).collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()));
			sumItemMap.put("date", "合计");
			dataList.add(sumItemMap);
		}

		// 4.构造返回数据结构
		Map resultMap = new HashMap<>();
		List<EwmsReportVo.WasteIncinerateHandleWasteInfo> wasteList = wasteSet.stream().map(entry ->
			new EwmsReportVo.WasteIncinerateHandleWasteInfo(entry.getKey(), entry.getValue())
		).collect(Collectors.toList());
		resultMap.put("wasteList", wasteList);
		resultMap.put("dataListdataList", dataList);
		return resultMap;
	}

	/**
	 * 查询系统年月列表
	 *
	 * @return
	 */
	@Override
	public List<String> selectYearMonthList() {
		return reportMapper.selectYearMonthList();
	}
}
